class Node(object):
    def __init__(self, data=None):
        self.data = data
        self.next = None
        self.prev = None


class Fifo:
    def __init__(self, max_length):
        self.head = Node()
        self.tail = Node()
        self.length = 0
        self.max_length = max_length

        self.head.next = self.tail
        self.tail.prev = self.head

    def is_empty(self):
        return self.length == 0

    def is_full(self):
        return self.length == self.max_length

    def unshifT(self, data):
        # assert not self.is_full()
        try:
            assert not self.is_full()
            newNode = Node()
            newNode.data = data

            pNode = self.tail.prev
            pNode.next = newNode
            newNode.prev = pNode

            self.tail.prev = newNode
            newNode.next = self.tail
            self.length += 1
        except:
            print('已满')

    def shifT(self):
        assert not self.is_empty()
        node = self.head.next
        nNode = node.next

        self.head.next = nNode
        nNode.prev = self.head
        self.length -= 1

        return node.data

    def __iter__(self):
        node = self.head.next
        while node != self.tail:
            yield node.data
            node = node.next

    def __len__(self):
        return self.length

if __name__ == "__main__":
    l = Fifo(10)

    for i in range(0, 10):
        l.unshifT(i)

    for i in l:
        print(i)
      
    # try:
    #     print("The count: %d" % (len(l)))
    #     l.unshifT(100)
    # except Exception:
    #     print("The FIFO is full")
    #     data = l.shifT()
    #     print("The first data is: %d" % (data))
    #     l.unshifT(100)
    #     print("Access every element.")
    #     for i in l:
    #         print(i)
     
    l.unshifT(20)